<script setup lang="ts">
import {
  defineProps,
  defineEmits,
  PropType,
  computed,
  useSlots,
  ref,
  h
} from "vue";
import renderSlot from "./types/index";
import { ArrowRight, ArrowDown } from "@element-plus/icons-vue";
import type { OptionsType, ColumnItem } from "./types/index.d";
const props = defineProps({
  tableData: {
    type: Array,
    required: true,
    default: () => []
  },
  columns: {
    type: Array as PropType<ColumnItem[]>,
    required: true,
    default: () => []
  },
  page: {
    type: Number,
    default: 1
  },
  limit: {
    type: Number,
    default: 10
  },
  pageSize: {
    type: Array as PropType<number[]>,
    default: () => [20, 50, 100, 200]
  },
  total: {
    type: Number,
    default: 0
  },
  isExpand: {
    type: Boolean,
    default: false
  },
  expandRowKeys: {
    type: Array as PropType<number[]>,
    default: () => []
  },
  tableOptionsArr: {
    type: Array as PropType<OptionsType[]>,
    default: () => []
  },
  isLoading: {
    type: Boolean,
    default: false
  }
});
const emits = defineEmits(["pagination"]);
function handleSizeChange(limit: number) {
  emits("pagination", { page: props.page, limit: limit });
}
function handleCurrentChange(page: number) {
  emits("pagination", { page: page, limit: props.limit });
}
// 动态判断是否有默认插槽
const slots = useSlots();
const hasDefaultSlot = Boolean(slots.default);
// 如果有默认插槽，自动添加操作列
const computedColumns = computed(() => {
  const columns = [...props.columns];
  if (hasDefaultSlot) {
    columns.push({
      label: "操作",
      prop: "operation",
      propsType: "operation",
      width: "250px"
    });
  }
  // 如果有expand插槽，添加展开列
  if (props.tableOptionsArr.includes("expand")) {
    columns.unshift({
      label: "展开",
      prop: "expand",
      type: "expand",
      width: 70 // 展开列,
    });
  }
  if (props.tableOptionsArr.includes("selection")) {
    columns.unshift({
      label: "",
      prop: "selection",
      type: "selection"
    });
  }
  return columns;
});
// 渲染不同类型的内容
function renderSlotContent(item: ColumnItem, row: any) {
  const renderer = renderSlot[item.propsType];
  if (item.prop == "expand") {
    return h("div", null, slots.expand({ row }));
  }
  return renderer(item, row);
}
</script>

<template>
  <el-table
    v-loading="props.isLoading"
    :data="props.tableData"
    style="width: 100%"
    border
    v-bind="$attrs"
    ref="tableRef"
    height="calc(100vh - 300px)"
    :header-cell-style="{ background: '#f5f7fa' }"
  >
    <!-- 动态渲染列 -->
    <el-table-column
      v-for="item in computedColumns"
      :key="item.prop || item.slots"
      :prop="item.prop"
      :label="item.label"
      :width="item.width"
      :align="item.align"
      :sortable="item.sortable"
      :type="item.type"
    >
      <!-- 插槽支持 -->
      <template
        v-if="item.propsType || item.type == 'expand'"
        #default="{ row }"
      >
        <component :is="renderSlotContent(item, row)" />
      </template>
    </el-table-column>
  </el-table>
  <div class="flex-c p-5">
    <el-pagination
      v-if="props.total > 0"
      :current-page="props.page"
      :page-size="props.limit"
      :page-sizes="props.pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="props.total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

<style lang="scss" scoped></style>
